package com.tedu.api.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * 迭代器:打印集合元素【接口】
 * 集合提供自己一套输出集合元素的方法---迭代器【类似for,增强for】
 * Iterator    接口
 * 包位置:java.util
 * 该接口是集合接口，提供遍历元素的相关操作：问、取、删
 * iterator()方法    返回值Iterator      ---Collection接口类已经存在方法
 * 作用：获取一个用于遍历当前集合迭代器的实现类实例
 * <p>
 * 遍历规则：问、取、删(删不是必须操作)
 */
public class Collection_iterator {
    @Test
    public void testIterator() {
        //创建集合
        Collection c1 = new ArrayList();
        c1.add("one");
        c1.add("two");
        c1.add("three");
        c1.add("four");
        c1.add("five");
        c1.add("six");
        //iterator()获取一个用于遍历当前集合迭代器的实现类实例
        Iterator it = c1.iterator();
        //理解：拿到集合所有元素，封装迭代器创建对象过程--理解迭代器实例
        //使用Iterator--获取集合的某个元素，规则：问、取、删
        //Iterator接口---hasNext() 获取集合元素
        //思考：？个元素    ---循环  while
        while (it.hasNext()) {//1.集合是否有元素
            // 迭代器集合：获取元素  next()获取元素   返回值Object
            String str = (String) it.next();//2.取：获取集合元素
            System.out.println("集合迭代器" + str);
        }
        //迭代器是否改变集合的元素内容
        System.out.println(c1);


    }

    /**
     * 普通for---遍历c1集合          集合:size()
     * 语法：for(int i=0;i<c1.size();i++){}
     * 增强for---遍历c1集合
     * for(Object c:c1){}
     * Iterator迭代器---集合提供接口
     */
    @Test
    public void testCollection() {
        //创建集合
        Collection c1 = new ArrayList();
        c1.add("one");
        c1.add("two");
        c1.add("three");
        c1.add("four");
        c1.add("five");
        c1.add("six");
        Iterator it = c1.iterator();
        for (int i = 1; i <= c1.size(); i++) {
            System.out.println("噗通for：" + i);//大阴
        }
        //增强for  遍历集合
        for (Object c : c1) {
            System.out.println("增强for：" + c);
        }

    }

    /**
     * remove()  删除   Iterator迭代器   增强for
     * 作用：删除相同的元素数据，提醒：问，取next方法【删】
     */
    @Test
    public void testRemove() {
        Collection c = new ArrayList();
        c.add("马嘉祺");
        c.add("牢大");
        c.add("蔡徐坤");
        //需求：通过迭代器删除  牢大
        Iterator it = c.iterator();
        while (it.hasNext()) {//问：有没有24号球衣
            String str = (String) it.next();        //取：有元素--打印元素
            c.remove("牢大");  //remove->是删除的          Collection存在romove()方法不能在迭代器删
            //删除一定是迭代器
            if ("牢大".equals(str)) {//如果牢大是我们拿到的str元素中
                it.remove();//那么，删除元素
            }
        }
        System.out.println("迭代器删除：" + c);


    }

    /**
     * 增强for  删除集合中元素是”牢大“
     * c.remove('牢大')是Collection的删除方法，并不是迭代器方法
     * 需求：删除集合中的元素”for“
     */
    @Test
    public void testFor() {
        Collection c = new ArrayList();
        c.add("马嘉祺");
        c.add("牢大");
        c.add("蔡徐坤");
        for (Object o : c) {//类型 类型引用：集合引用
            String str = (String) o;//强转：拿到字符串类型
            if ("牢大".equals(str)) {
                c.remove(o);

            }

        }
        System.out.println("哎呦你干嘛：" + c);
    }

    /**
     * E 泛型 element JDK1.5后的新特性 结合出现 约束集合类型[基本数据类型、引用类型、包装类]
     * 泛型的原型:Object,泛型是编译器认可的，JVM虚拟机并不认可
     * 使用泛型是告诉编译器应该把泛型当作Object类型执行，便于编译器检查
     * 类型以及自动造型操作
     * <p>
     * 泛型使用：
     * Collection<类型：基本类型、引用类型、包装类>
     * c=new ArrayList<类型：基本类型、引用类型、包装类>
     * <p>
     * JDK1.7泛型使用：
     * Collection<类型：基本类型、引用类型、包装类> c
     * =new ArrayList<>();
     * <p>
     * 泛型，自动推荐    通配符：？  表示任意类型
     * Collection<类型:?>
     * =new ArrayList<>();
     * <p>
     * Collection<类型:? extends/super 父类/接口/类> c=new ArrayList<>();
     *
     * 优点：保证类型安全，提高代码重用性和灵活性
     * 限定集合传入对应类型
     *
     *
     */
    @Test
    public void testType() {
        Collection<?> c1 = new ArrayList<>();
        //  c1.add(1);c1.add("1");c1.add(new Object());
        c1.add(null);//空   结论:并不是匹配所有类型，有上界要求，只能传null，没有意义


        Collection<String> c = new ArrayList<>();//加上<>    约束只能用String类型
        c.add("456");
        c.add("789");
        c.add("123");
        //遍历Iterator
        Iterator<String> it = c.iterator();
        while (it.hasNext()) {
            String str = it.next();
            System.out.println(str);
        }
    }
}

//---限定集合传入对应类型
class Fruit{
    private String name;//成员变量

    public Fruit(String name) {//有参构造器
        this.name = name;
    }

    public String getName() {//方法
        return name;
    }
}
class Apple extends Fruit{
    public Apple() {
        super("苹果");//调用父类有参构造器，传入name名称
    }
}
class Orange extends Fruit{
    public Orange() {
        super("袄孕之");//调用父类有参构造器，传入name名称
    }
}
//测试类---泛型上界
class TestJob{
    //泛型上界  1.定义静态方法，制定泛型规则--集合中类型约定为🍎和袄孕之
    public static void printFruit(Collection<? extends Fruit> fruits){
        //2.增强for循环打印：集合中类型约定为Apple与Orange
        for(Fruit fruit:fruits){
            //3.方法能进入：Apple或Orange---打印名字
            System.out.println(fruit.getName());


        }
    }
//主方法：测试功能
    public static void main(String[] args) {
        Collection<Apple> apples=new ArrayList<>();
        apples.add(new Apple());//集合对象添加：Apple对象
        Collection<Orange> oranges=new ArrayList<>();
        oranges.add(new Orange());//集合对象添加：Orange对象
        printFruit(apples);//测试：打印出：苹果
        printFruit(oranges);//测试：打印出：橘子
        //假设：西瓜
        Collection<String> strings=new ArrayList<>();
        strings.add(new String());
        //printFruit(strings);//只能添加上界限定的    180185左右

    }
}




